﻿#include "framework.h"
#include "Block.h"

// ██
// ██

// 全局变量
extern ColorGrid gExistentBlocks[GAME_BOARD_GRID_COUNT_V][GAME_BOARD_GRID_COUNT_H];

// 函数声明
static void Block1_EnterPreview(Block*, HDC);
static void Block1_Erase(Block*);
static int Block1_GetBottom(Block*);
static int Block1_GetTop(Block*);
static void Block1_HandleCannotMoveDown(Block*);
static BOOL Block1_MoveDown(Block*);
static void Block1_MoveLeft(Block*);
static void Block1_MoveRight(Block*);
static void Block1_Transform(Block*);

/**
 * 创建方块1。
 * @return 方块1
 */
Block* New_Block1() {
    // 创建方块
    Block* block = New_Block();

    // 初始化数据
    block->mBlocks[1][1].mUsed = block->mBlocks[1][2].mUsed = block->mBlocks[2][1].mUsed = block->mBlocks[2][2].mUsed = TRUE;

    // 初始化函数
    block->enterPreview = Block1_EnterPreview;
    block->erase = Block1_Erase;
    block->getBottom = Block1_GetBottom;
    block->getTop = Block1_GetTop;
    block->handleCannotMoveDown = Block1_HandleCannotMoveDown;
    block->moveDown = Block1_MoveDown;
    block->moveLeft = Block1_MoveLeft;
    block->moveRight = Block1_MoveRight;
    block->transform = Block1_Transform;

    return block;
}

/**
 * 进入预览区域。
 * @param block     方块1
 * @param drawer    绘图者
 */
static void Block1_EnterPreview(Block* block, HDC drawer) {
    RECT rect = { 0 };
    int x = PREVIEW_WIDTH / 2 - GRID_SIZE;
    int y = PREVIEW_HEIGHT / 2 - GRID_SIZE;

    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            rect.left = x + GRID_SIZE * j;
            rect.top = y + GRID_SIZE * i;
            rect.right = rect.left + GRID_SIZE;
            rect.bottom = rect.top + GRID_SIZE;
            SetBkColor(drawer, block->mColor);
            ExtTextOut(drawer, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
            DrawEdge(drawer, &rect, EDGE_RAISED, BF_RECT);
        }
    }
}

/**
 * 擦除。
 * @param block 方块1
 */
static void Block1_Erase(Block* block) {
    RECT rect = { 0 };

    rect.left = GRID_SIZE * (block->mLine + 1);
    rect.top = GRID_SIZE * (block->mRow + 1);
    rect.right = rect.left + GRID_SIZE * 2;
    rect.bottom = rect.top + GRID_SIZE * 2;
    block->eraseRect(block, &rect);
}

/**
 * 获取顶端所在的行数。顶端是指方块最上方的有效格。
 * @param block 方块1
 * @return 顶端所在的行数
 */
static int Block1_GetTop(Block* block) {
    return block->mRow + 1;
}

/**
 * 获取底端所在的行数。底端是指方块最下方的有效格。
 * @param block 方块1
 * @return 底端所在的行数
 */
static int Block1_GetBottom(Block* block) {
    return block->mRow + 2;
}

/**
 * 对不能下落的处理。
 * @param block 方块1
 */
static void Block1_HandleCannotMoveDown(Block* block) {
    gExistentBlocks[block->mRow + 1][block->mLine + 1].mUsed = 
    gExistentBlocks[block->mRow + 1][block->mLine + 2].mUsed = 
    gExistentBlocks[block->mRow + 2][block->mLine + 1].mUsed = 
    gExistentBlocks[block->mRow + 2][block->mLine + 2].mUsed = TRUE;
    gExistentBlocks[block->mRow + 1][block->mLine + 1].mColor = 
    gExistentBlocks[block->mRow + 1][block->mLine + 2].mColor = 
    gExistentBlocks[block->mRow + 2][block->mLine + 1].mColor = 
    gExistentBlocks[block->mRow + 2][block->mLine + 2].mColor = block->mColor;
}

/**
 * 下落。
 * @param block 方块1
 * @return 成功则返回 TRUE，否则返回 FALSE
 */
static BOOL Block1_MoveDown(Block* block) {
    if (block->mRow == 17) {
        block->handleCannotMoveDown(block);
        return FALSE;
    }
    if (gExistentBlocks[block->mRow + 3][block->mLine + 1].mUsed ||
        gExistentBlocks[block->mRow + 3][block->mLine + 2].mUsed) {
        block->handleCannotMoveDown(block);
        return FALSE;
    }

    return Block_MoveDown(block);
}

/**
 * 左移。
 * @param block 方块1
 */
static void Block1_MoveLeft(Block* block) {
    if (block->mLine == -1) {
        return;
    }
    if (gExistentBlocks[block->mRow + 1][block->mLine].mUsed ||
        gExistentBlocks[block->mRow + 2][block->mLine].mUsed) {
        return;
    }

    Block_MoveLeft(block);
}

/**
 * 右移。
 * @param block 方块1
 */
static void Block1_MoveRight(Block* block) {
    if (block->mLine == 7) {
        return;
    }
    if (gExistentBlocks[block->mRow + 1][block->mLine + 3].mUsed ||
        gExistentBlocks[block->mRow + 2][block->mLine + 3].mUsed) {
        return;
    }

    Block_MoveRight(block);
}

/**
 * 变形。
 * @param block 方块1
 */
static void Block1_Transform(Block* block) {
    UNREFERENCED_PARAMETER(block);
}
